import { Response } from 'express';
import { AuthenticatedRequest } from '@/middleware/auth';
import { Expense } from '@/models/Expense';
import { Income } from '@/models/Income';
import { FuelRecord } from '@/models/FuelRecord';

// 工具函数：按月分组
function groupByMonth(records: any[], dateField: string, valueField: string) {
  const result: Record<string, number> = {};
  for (const rec of records) {
    const d = new Date(rec[dateField]);
    const key = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}`;
    result[key] = (result[key] || 0) + (rec[valueField] || 0);
  }
  return result;
}

/**
 * @swagger
 * /api/charts/fuel-trend:
 *   get:
 *     summary: 油耗趋势图表数据
 *     tags: [图表]
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: query
 *         name: vehicleId
 *         schema:
 *           type: string
 *         description: 车辆ID
 *       - in: query
 *         name: startDate
 *         schema:
 *           type: string
 *           format: date
 *         description: 开始日期
 *       - in: query
 *         name: endDate
 *         schema:
 *           type: string
 *           format: date
 *         description: 结束日期
 *     responses:
 *       200:
 *         description: 获取成功
 */
export const fuelTrendChart = async (
  req: AuthenticatedRequest,
  res: Response
): Promise<void> => {
  try {
    const { vehicleId, startDate, endDate } = req.query;
    if (!vehicleId) {
      res.status(400).json({ success: false, message: '缺少车辆ID' });
      return;
    }
    const filter: any = { vehicleId };
    if (startDate || endDate) {
      filter.date = {};
      if (startDate) filter.date.$gte = new Date(startDate as string);
      if (endDate) filter.date.$lte = new Date(endDate as string);
    }
    const records = await FuelRecord.find(filter).sort({ date: 1 });
    const data = groupByMonth(records, 'date', 'quantity');
    res
      .status(200)
      .json({ success: true, message: '油耗趋势数据获取成功', data });
  } catch (error) {
    res.status(500).json({ success: false, message: '服务器内部错误' });
  }
};

/**
 * @swagger
 * /api/charts/expense-trend:
 *   get:
 *     summary: 费用趋势图表数据
 *     tags: [图表]
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: query
 *         name: vehicleId
 *         schema:
 *           type: string
 *         description: 车辆ID
 *       - in: query
 *         name: startDate
 *         schema:
 *           type: string
 *           format: date
 *         description: 开始日期
 *       - in: query
 *         name: endDate
 *         schema:
 *           type: string
 *           format: date
 *         description: 结束日期
 *     responses:
 *       200:
 *         description: 获取成功
 */
export const expenseTrendChart = async (
  req: AuthenticatedRequest,
  res: Response
): Promise<void> => {
  try {
    const { vehicleId, startDate, endDate } = req.query;
    const filter: any = { userId: req.userId };
    if (vehicleId) filter.vehicleId = vehicleId;
    if (startDate || endDate) {
      filter.date = {};
      if (startDate) filter.date.$gte = new Date(startDate as string);
      if (endDate) filter.date.$lte = new Date(endDate as string);
    }
    const records = await Expense.find(filter).sort({ date: 1 });
    const data = groupByMonth(records, 'date', 'amount');
    res
      .status(200)
      .json({ success: true, message: '费用趋势数据获取成功', data });
  } catch (error) {
    res.status(500).json({ success: false, message: '服务器内部错误' });
  }
};

/**
 * @swagger
 * /api/charts/income-trend:
 *   get:
 *     summary: 收入趋势图表数据
 *     tags: [图表]
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: query
 *         name: vehicleId
 *         schema:
 *           type: string
 *         description: 车辆ID
 *       - in: query
 *         name: startDate
 *         schema:
 *           type: string
 *           format: date
 *         description: 开始日期
 *       - in: query
 *         name: endDate
 *         schema:
 *           type: string
 *           format: date
 *         description: 结束日期
 *     responses:
 *       200:
 *         description: 获取成功
 */
export const incomeTrendChart = async (
  req: AuthenticatedRequest,
  res: Response
): Promise<void> => {
  try {
    const { vehicleId, startDate, endDate } = req.query;
    const filter: any = { userId: req.userId };
    if (vehicleId) filter.vehicleId = vehicleId;
    if (startDate || endDate) {
      filter.date = {};
      if (startDate) filter.date.$gte = new Date(startDate as string);
      if (endDate) filter.date.$lte = new Date(endDate as string);
    }
    const records = await Income.find(filter).sort({ date: 1 });
    const data = groupByMonth(records, 'date', 'amount');
    res
      .status(200)
      .json({ success: true, message: '收入趋势数据获取成功', data });
  } catch (error) {
    res.status(500).json({ success: false, message: '服务器内部错误' });
  }
};

/**
 * @swagger
 * /api/charts/expense-pie:
 *   get:
 *     summary: 费用分类饼图数据
 *     tags: [图表]
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: query
 *         name: vehicleId
 *         schema:
 *           type: string
 *         description: 车辆ID
 *       - in: query
 *         name: startDate
 *         schema:
 *           type: string
 *           format: date
 *         description: 开始日期
 *       - in: query
 *         name: endDate
 *         schema:
 *           type: string
 *           format: date
 *         description: 结束日期
 *     responses:
 *       200:
 *         description: 获取成功
 */
export const expensePieChart = async (
  req: AuthenticatedRequest,
  res: Response
): Promise<void> => {
  try {
    const { vehicleId, startDate, endDate } = req.query;
    const filter: any = { userId: req.userId };
    if (vehicleId) filter.vehicleId = vehicleId;
    if (startDate || endDate) {
      filter.date = {};
      if (startDate) filter.date.$gte = new Date(startDate as string);
      if (endDate) filter.date.$lte = new Date(endDate as string);
    }
    const records = await Expense.find(filter);
    const typeMap: Record<string, number> = {};
    for (const rec of records) {
      typeMap[rec.type] = (typeMap[rec.type] || 0) + (rec.totalAmount || 0);
    }
    res.status(200).json({
      success: true,
      message: '费用分类饼图数据获取成功',
      data: typeMap,
    });
  } catch (error) {
    res.status(500).json({ success: false, message: '服务器内部错误' });
  }
};

/**
 * @swagger
 * /api/charts/mileage-trend:
 *   get:
 *     summary: 行程趋势图表数据
 *     tags: [图表]
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: query
 *         name: vehicleId
 *         schema:
 *           type: string
 *         description: 车辆ID
 *       - in: query
 *         name: startDate
 *         schema:
 *           type: string
 *           format: date
 *         description: 开始日期
 *       - in: query
 *         name: endDate
 *         schema:
 *           type: string
 *           format: date
 *         description: 结束日期
 *     responses:
 *       200:
 *         description: 获取成功
 */
export const mileageTrendChart = async (
  req: AuthenticatedRequest,
  res: Response
): Promise<void> => {
  try {
    const { vehicleId, startDate, endDate } = req.query;
    if (!vehicleId) {
      res.status(400).json({ success: false, message: '缺少车辆ID' });
      return;
    }
    const filter: any = { vehicleId };
    if (startDate || endDate) {
      filter.date = {};
      if (startDate) filter.date.$gte = new Date(startDate as string);
      if (endDate) filter.date.$lte = new Date(endDate as string);
    }
    const records = await FuelRecord.find(filter).sort({ date: 1 });
    // 按月统计里程增量
    const result: Record<string, number> = {};
    let lastOdometer: number | null = null;
    for (const rec of records) {
      const d = new Date(rec.date);
      const key = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}`;
      if (lastOdometer !== null) {
        result[key] = (result[key] || 0) + (rec.odometer - lastOdometer);
      }
      lastOdometer = rec.odometer;
    }
    res
      .status(200)
      .json({ success: true, message: '行程趋势数据获取成功', data: result });
  } catch (error) {
    res.status(500).json({ success: false, message: '服务器内部错误' });
  }
};
